package org.papervision3d.core.geom
{
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.utils.Dictionary;
    
    import org.papervision3d.Papervision3D;
    import org.papervision3d.core.*;
    import org.papervision3d.core.proto.*;
    import org.papervision3d.core.geom.*;
    
    import org.papervision3d.objects.DisplayObject3D;
    
    // The Mesh3D class lets you create and display solid 3D objects made of vertices and triangular polygons.
    public class Mesh3D extends Vertices3D
    {
        public var faces:Array = new Array();

        // [internal-use]
        public var drawtriangles:Array = new Array();
    
        // The default material for the object instance. Materials collect data about how objects appear when rendered.
        public var material:MaterialObject3D;
    
        // Creates a new Mesh object.
        // The Mesh DisplayObject3D class lets you create and display solid 3D objects made of vertices and triangular polygons.
        // @param material   A MaterialObject3D object that contains the material properties of the object.
        // @param vertices   An array of Vertex3D objects for the vertices of the mesh.
        // @param faces      An array of Face3D objects for the faces of the mesh.
        // @param initObject [optional] - An object that contains user defined properties with which to populate the newly created DisplayObject3D.
        // It includes x, y, z, rotationX, rotationY, rotationZ, scaleX, scaleY scaleZ and a user defined extra object.
        // If extra is not an object, it is ignored. All properties of the extra field are copied into the new instance. The properties specified with extra are publicly available.
        //   sortFaces: Z-depth sorting when rendering. Some objects might not need it. Default is false (faster).
        //   showFaces: Use only if each face is on a separate MovieClip container. Default is false.
        public function Mesh3D(material:MaterialObject3D, name:String = null, initObject:Object = null)
        {
            super(name, initObject);
    
            this.material = material || MaterialObject3D.DEFAULT;
        }
        
        
        
       
     
    
        // Projects three dimensional coordinates onto a two dimensional plane to simulate the relationship of the camera to subject.
        // This is the first step in the process of representing three dimensional shapes two dimensionally.
        // @param camera Camera3D object to render from.
        public override function project(parent:DisplayObject3D, camera:CameraObject3D, callback:TraverseCallback):void
        {
            super.project(parent, camera, callback);

            var faces:Array = this.faces;
            var tri:DrawTriangle;
            var face:Face3D;
    
            for (var i:int = 0; face = faces[i]; i++)
            {
            	
                if (face.drawtriangle == null)
                    face.drawtriangle = new DrawTriangle();



                tri = face.drawtriangle;

                tri.v0 = face.v0.projected;
                tri.v1 = face.v1.projected;
                tri.v2 = face.v2.projected;
            	tri.Zoffset = _concatZoffset;
    
                tri.calc();

                if (tri.minZ < 0){
                	//trace("Tri.minZ < 0 !!!", tri.minZ );
                    continue;
                }

                tri.material = face.getMaterial(this);

                if (tri.material)
                {
                    if (tri.material.invisible)
                        continue;

                    if (tri.material.oneSide)
                        if (tri.material.opposite != (tri.area < 0))
                            continue;
                }

                tri.uv0 = face.uv0;
                tri.uv1 = face.uv1;
                tri.uv2 = face.uv2;

                if (tri.material.bitmap)
                {
                    if (face.texturemapping == null)
                        face.texturemapping = tri.transformUV();

                    tri.texturemapping = face.texturemapping;
                }

                callback.face(face, this);
            }
        }
        
        override public function dispose():void {
        	super.dispose();
        	
        	trace( "**************** MESH DiSPOSE ,"+name+"********************" );
        	for ( var i : String in faces ) {
        		faces[i] = null;
        		delete faces[i];
        	}
        	for ( i in drawtriangles ) {
        		drawtriangles[i] = null;
        		delete drawtriangles[i];
        	}
        }
    }
}
